001 /** 002 * Copyright 2003-2004 The Apache Software Foundation 003 * Copyright 2005 Stephen McConnell 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package net.dpml.cli.builder; 018 019 import java.util.HashSet; 020 import java.util.Iterator; 021 import java.util.Set; 022 023 import net.dpml.cli.Argument; 024 import net.dpml.cli.Option; 025 import net.dpml.cli.validation.ClassValidator; 026 import net.dpml.cli.validation.DateValidator; 027 import net.dpml.cli.validation.FileValidator; 028 import net.dpml.cli.validation.NumberValidator; 029 import net.dpml.cli.validation.URLValidator; 030 import net.dpml.cli.validation.Validator; 031 032 /** 033 * Builds Options using a String pattern 034 * 035 * @author <a href="http://www.dpml.net">Digital Product Meta Library</a> 036 * @version 1.0.0 037 */ 038 public class PatternBuilder 039 { 040 private final GroupBuilder m_gbuilder; 041 private final DefaultOptionBuilder m_obuilder; 042 private final ArgumentBuilder m_abuilder; 043 private final Set m_options = new HashSet(); 044 045 /** 046 * Creates a new PatternBuilder 047 */ 048 public PatternBuilder() 049 { 050 this( 051 new GroupBuilder(), 052 new DefaultOptionBuilder(), 053 new ArgumentBuilder() ); 054 } 055 056 /** 057 * Creates a new PatternBuilder 058 * @param gbuilder the GroupBuilder to use 059 * @param obuilder the DefaultOptionBuilder to use 060 * @param abuilder the ArgumentBuilder to use 061 */ 062 public PatternBuilder( 063 final GroupBuilder gbuilder, 064 final DefaultOptionBuilder obuilder, 065 final ArgumentBuilder abuilder ) 066 { 067 m_gbuilder = gbuilder; 068 m_obuilder = obuilder; 069 m_abuilder = abuilder; 070 } 071 072 /** 073 * Creates a new Option instance. 074 * @return a new Option instance 075 */ 076 public Option create() 077 { 078 final Option option; 079 if( m_options.size() == 1 ) 080 { 081 option = (Option) m_options.iterator().next(); 082 } 083 else 084 { 085 m_gbuilder.reset(); 086 for( final Iterator i = m_options.iterator(); i.hasNext();) 087 { 088 m_gbuilder.withOption( (Option) i.next() ); 089 } 090 option = m_gbuilder.create(); 091 } 092 reset(); 093 return option; 094 } 095 096 /** 097 * Resets this builder 098 * @return the builder 099 */ 100 public PatternBuilder reset() 101 { 102 m_options.clear(); 103 return this; 104 } 105 106 private void createOption( final char type, final boolean required, final char opt ) 107 { 108 final Argument argument; 109 if( type != ' ' ) 110 { 111 m_abuilder.reset(); 112 m_abuilder.withValidator( validator( type ) ); 113 if( required ) 114 { 115 m_abuilder.withMinimum( 1 ); 116 } 117 if( type != '*' ) 118 { 119 m_abuilder.withMaximum( 1 ); 120 } 121 argument = m_abuilder.create(); 122 } 123 else 124 { 125 argument = null; 126 } 127 128 m_obuilder.reset(); 129 m_obuilder.withArgument( argument ); 130 m_obuilder.withShortName( String.valueOf( opt ) ); 131 m_obuilder.withRequired( required ); 132 m_options.add( m_obuilder.create() ); 133 } 134 135 /** 136 * Builds an Option using a pattern string. 137 * @param pattern the pattern to build from 138 */ 139 public void withPattern( final String pattern ) 140 { 141 int sz = pattern.length(); 142 char opt = ' '; 143 char ch = ' '; 144 char type = ' '; 145 boolean required = false; 146 147 for( int i=0; i < sz; i++ ) 148 { 149 ch = pattern.charAt( i ); 150 switch( ch ) 151 { 152 case '!' : 153 required = true; 154 break; 155 case '@' : 156 case ':' : 157 case '%' : 158 case '+' : 159 case '#' : 160 case '<' : 161 case '>' : 162 case '*' : 163 case '/' : 164 type = ch; 165 break; 166 default : 167 if( opt != ' ' ) 168 { 169 createOption( type, required, opt ); 170 required = false; 171 type = ' '; 172 } 173 opt = ch; 174 } 175 } 176 if( opt != ' ' ) 177 { 178 createOption( type, required, opt ); 179 } 180 } 181 182 private static Validator validator( final char c ) 183 { 184 switch( c ) 185 { 186 case '@' : 187 final ClassValidator classv = new ClassValidator(); 188 classv.setInstance( true ); 189 return classv; 190 case '+' : 191 final ClassValidator instancev = new ClassValidator(); 192 return instancev; 193 //case ':':// no validator needed for a string 194 case '%' : 195 return NumberValidator.getNumberInstance(); 196 case '#' : 197 return DateValidator.getDateInstance(); 198 case '<' : 199 final FileValidator existingv = new FileValidator(); 200 existingv.setExisting( true ); 201 existingv.setFile( true ); 202 return existingv; 203 case '>' : 204 case '*' : 205 return new FileValidator(); 206 case '/' : 207 return new URLValidator(); 208 default : 209 return null; 210 } 211 } 212 }